package com.jwpdk.appframework.controller;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.jwpdk.appframework.data.DataMap;
import com.jwpdk.appframework.data.IData;
import com.jwpdk.common.Constant;
import com.jwpdk.dbframework.Transaction;
import com.jwpdk.dbframework.TransactionManager;
import com.jwpdk.util.ReflectionUtils;
/**
 * 控制器
 * @author 王志伟
 */
public class Controller {

	private final Logger		log			= Logger.getLogger(this.getClass());
	private final String		ACTIONKEY	= "action";
	private final String		METHODKEY	= "method";
	private HttpServletRequest	request;
	private HttpServletResponse	response;
	private Dispatcher			dispatcher;
	private IData				actionMethodCode;

	public Controller(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
		this.dispatcher = Dispatcher.getInstance();
	}

	/**
	 * TAG请求分发
	 * @throws ServletException
	 * @throws Exception
	 */
	public void tagService(FilterChain chain) {
		try {
			Transaction transaction = new Transaction(Constant.TAG_TRANSACTION);
			TransactionManager tManager = TransactionManager.getInstance();
			tManager.beginTransaction(transaction);
			chain.doFilter(request,response);
			tManager.endTransaction(transaction);
		} catch ( Exception e ) {
			log.error(e);
			e.printStackTrace();
		}
	}

	/**
	 * ACTION请求分发
	 * @throws ServletException
	 * @throws Exception
	 */
	public void actionService() throws ServletException, Exception {
		// action 请求事务
		Transaction actionTransaction = new Transaction(Constant.ACTION_TRANSACTION);
		TransactionManager tManager = TransactionManager.getInstance();
		try {
			tManager.beginTransaction(actionTransaction);
			parseActionMethodCode();
			Class< ?> hd = getHandler();
			String methodStr = getMethod();
			Object object = hd.newInstance();
			// 调用Handler类中的initParameters方法传递请求
			ReflectionUtils.invokeMethod(object,"initParameters",new Class[] { HttpServletRequest.class, HttpServletResponse.class },new Object[] { request, response });
			// 调用Handler的请求方法方法
			ReflectionUtils.invokeMethod(object,methodStr,null,null);
		} catch ( Exception e ) {
			throw e;
		} finally {
			// 关闭事务
			tManager.endTransaction(actionTransaction);
		}
	}

	/**
	 * 获取请求方法的字串
	 * @return
	 * @throws Exception
	 */
	private String getMethod() {
		return actionMethodCode.getString(METHODKEY);
	}

	/**
	 * 获取实现Handler
	 * @return
	 * @throws Exception
	 */
	private Class getHandler() throws Exception {
		String actionCode = dispatcher.getActionCode(actionMethodCode.getString(ACTIONKEY));
		Class hd = Class.forName(actionCode);
		if ( !Handler.class.isAssignableFrom(hd) ) {
			throw new Exception(String.format("%s 未继承 com.jwpdk.appframework.controller.Handler 父类",actionCode));
		}
		return hd;
	}

	/**
	 * 解析请求的Action字串
	 * @see /manage/ajax/Action!getfsc.action manage.ajax.Action getfsc
	 *      /manage/ajax/Action!getfsc manage.ajax.Action getfsc
	 *      /manage/ajax/Action.action manage.ajax.Action execute
	 *      /manage/ajax/Action manage.ajax.Action execute /Action Action
	 *      execute
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private void parseActionMethodCode() {
		actionMethodCode = new DataMap();
		String url = request.getServletPath();
		int d = url.lastIndexOf("!") > -1 ? url.lastIndexOf("!") : url.lastIndexOf(".") > -1 ? url.lastIndexOf(".") : url.endsWith("/") ? url.length() - 1 : url.length();
		int ms = url.lastIndexOf("!") > -1 ? url.lastIndexOf("!") : -1;
		int me = url.lastIndexOf(".") > -1 ? url.lastIndexOf(".") : url.length();
		String method = ms != -1 ? url.substring(ms + 1,me) : "execute";
		String actionCode = url.substring(1,d);
		actionMethodCode.put(ACTIONKEY,actionCode.replace('/','.'));
		actionMethodCode.put(METHODKEY,method);
		if ( log.isDebugEnabled() ) {
			log.debug(actionMethodCode);
		}
	}
}
